export default class VisibilityAnalysisClass {
    /**
     * 初始化
     * @param {Cesium.viewer} viewer
     * @param {非作者不建议使用} tileset_EXPERIMENTAL 
     */
    constructor(viewer, tileset_EXPERIMENTAL) {
            this.viewer = viewer
            this.positions = []
            this.resultPolylines = []
            this.tileset = tileset_EXPERIMENTAL
        }
        /**
         * 设置通视分析的视点和目标点
         * @param {Cesium.Cartesian3} viewPosition 
         * @param {Cesium.Cartesian3} targetPosition 
         */
    setPositions(viewPosition, targetPosition) {
            this.positions = [viewPosition, targetPosition]
        }
        /**
         * 设置position的向上偏移高度，避免嵌入模型中
         * @param {number} offsetHei 
         */
    useOffsetHeight(offsetHei) {
        this.positions = this.positions.map((pos => {
            let cartographic = Cesium.Cartographic.fromCartesian(pos);
            let lon = Cesium.Math.toDegrees(cartographic.longitude);
            let lat = Cesium.Math.toDegrees(cartographic.latitude);
            let hei = cartographic.height
            return Cesium.Cartesian3.fromDegrees(lon, lat, hei + offsetHei)
        }))
    }

    /**
     * 通视分析
     */
    startAnalysis() {
        // 计算射线的方向，目标点left 视域点right
        var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.positions[1], this.positions[0], new Cesium.Cartesian3()), new Cesium.Cartesian3());
        // 建立射线
        var ray = new Cesium.Ray(this.positions[0], direction);

        //获取射线确定的矩形内所有的features
        //如果初始化传入了tileset 就采用实验性的方法
        var objectsToExclude = Cesium.defined(this.tileset) ? this.getObjectsToExclude_EXPERIMENTAL(this.tileset) : this.getObjectsToExclude(this.positions)

        var result = this.viewer.scene.pickFromRay(ray, objectsToExclude); //计算射线与objectsToExclude交互点，返回第一个交点
        this.resultPolylines = this.showIntersection(result, this.positions[1], this.positions[0]);
    }

    /**
     * 获取两点构成的矩形内所有的要素
     * @param {Cesium.Cartesian3[]} positions
     * @returns {}  两点构成的矩形内所有的要素数组
     */
    getObjectsToExclude(positions) {
        return []
    }

    /**
     * 实验性，暂无官方接口，使用的是tileset._selectedTiles .....
     * @param {Cesium.Cartesian3[]} positions
     * @returns {}  [tileset._selectedTiles[i].content.getFeature(x)]
     */
    getObjectsToExclude_EXPERIMENTAL(tileset) {
        var features = []
        tileset._selectedTiles.forEach((tile) => {
            const { content, content: { featuresLength } } = tile
            for (let i = 0; i < featuresLength; i++) {
                features.push(content.get(i))
            }
        })
        return features
    }

    /**
     * 处理交互点
     * @param {*} result 
     * @param {Cesium.Cartesian3} targetPosition 
     * @param {Cesium.Cartesian3} viewPosition 
     * @returns 
     */
    showIntersection(result, targetPosition, viewPosition) {
        let resultPolylines = [];
        let resultLine;
        //Cesium.defined ....... souce/core/defined.js
        if (Cesium.defined(result) && Cesium.defined(result.object)) {
            resultLine = this.drawResultLine(viewPosition, result.position, Cesium.Color.CHARTREUSE); // 可视区域
            resultPolylines.push(resultLine);
            resultLine = this.drawResultLine(result.position, targetPosition, Cesium.Color.RED); // 不可视区域
            resultPolylines.push(resultLine);
        } else {
            resultLine = this.drawResultLine(viewPosition, targetPosition, Cesium.Color.CHARTREUSE);
            resultPolylines.push(resultLine);
        }
        return resultPolylines;
    }

    /**
     * 绘制不同颜色的直线
     * @param {Cesium.Cartesian3} startPosition 
     * @param {Cesium.Cartesian3} destPosition 
     * @param {Cesium.Color} color 
     * @returns {viewer.entities.add(...)}
     */
    drawResultLine(startPosition, destPosition, color) {
        return this.viewer.entities.add({
            polyline: {
                positions: [startPosition, destPosition],
                width: 5,
                material: color
            }
        })
    }
}